package com.naiterui.ehp.bs.emr.entity.mongo;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.naiterui.ehp.bp.bo.emr.MedicalRecordSettingBO;
import com.naiterui.ehp.bp.utils.date.DateUtil;

import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * 病历记录
 *
 * @author lichaopi
 * @since 1.0.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Document(collection = "medical_record")
public class MedicalRecord implements Serializable {

    @Deprecated
    public static final int CASETYPE_OLDRECORD = 0;
    @Deprecated
    public static final int CASETYPE_OLDCASE = 1;
    public static final int CASETYPE_RECOM = 2;
    public static final int CASETYPE_PATIENTRECORD = 3;
    public static final int CASETYPE_DOCTORRECORD = 4;
    @Deprecated
    public static final int CASETYPE_OLDDESREOCRD = 5;
    @Deprecated
    public static final int CASETYPE_OLDDESRECOM = 6;
    public static final int CASETYPE_DOCTORRECORD_RECOM = 7;
    public static final int CASETYPE_CONSULT = 8;
    public static final int CASETYPE_PATIENT_SCALE = 9;
    /**
     * 病历失效状态 正常 0
     */
    public static final int INVALID_STATUS_NORMAL = 0;
    /**
     * 病历失效状态 失效 1
     */
    public static final int INVALID_STATUS_INVALID = 1;
    /**
     * 暂存
     */
    public static final int TEMPORARY_YES = 1;
    /**
     * 非暂存
     */
    public static final int TEMPORARY_NO = 2;
    /**
     * 已发送
     */
    public static final boolean SEND_YES = true;
    /**
     * 病历删除状态：1：已删除
     */
    public static final int AVAILABLE_YES = 1;
    /**
     * 病历删除状态：0：未删除
     */
    public static final int AVAILABLE_NO = 0;


    /**
     * 签名开关：1/签名，2/不签名
     */
    public static final int SIGN_SWITCH_ON = 1;
    public static final int SIGN_SWITCH_OFF = 2;

    private static final long serialVersionUID = 5576719509864042122L;

    @Id
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String id;
    /**
     * 医生id
     */
    private Long doctorId;
    /**
     * 医生姓名
     */
    private String doctorName;
    /**
     * 医生职称
     */
    private String title;
    /**
     * 科室
     */
    private String department;
    /**
     * 医院名称
     */
    private String hospitalName;

    /**
     * 医院id
     */
    private Integer hospitalId;

    /**
     * 科室id
     */
    private Integer departmentId;
    /**
     * 患者id
     */
    private Long patientId;
    /**
     * 就诊人id
     */
    private Long inquirerId;

    /**
     * 患者姓名
     */
    private String name;
    /**
     * 0女1男2未知
     */
    private Integer gender;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 年龄单位: 单位固定为（天），和age为预留字段
     */
    private String ageUnit;

    /**
     * 显示年龄
     */
    private String ageStr;
    /**
     * 0:原诊疗记录,1:患者原病例,2:系统处方,3:患者发送病例,4:病历填写病历,5:带基本病情诊疗记录,6:带基本病情系统处方,7:带处方病历,8:线上诊室病历,9:患者填写量表
     */
    private Integer caseType;
    /**
     * 就诊人与患者关系：参考InquirerRelationEnum, 只做记录，实际数据以就诊人表为准
     */
    private Integer relation;

    /**
     * 同步数据标识
     */
    private Integer signs;
    /**
     * 暂存标识
     */
    private Integer temporary;
    /**
     * 发送标识：true已发送
     */
    private Boolean send;

    /**
     * 删除标识：1：删除：0或为空未删除
     */
    private Integer available;

    /**
     * 病例医生白名单:  病例中的医生信息逐步迁移至此——海南版本新增
     */
    private List<DoctorInfo> doctors;

    /**
     * 关联会话信息
     */
    private SessionInfo sessionInfo;

    /**
     * 签名开关：1/签名，2/不签名
     */
    private Integer signSwitch;

    /**
     * 签名信息——海南版本新增
     */
    private SignInfo signInfo;

    /**
     * 医生填写病历
     */
    private MedicalRecordDoctor recordDoctor;
    /**
     * 患者发送病历
     */
    private MedicalRecordFromPatient recordPatient;
    /**
     * 系统处方
     */
    private MedicalRecordRecom recordRecom;
    /**
     * 线上诊室病历
     */
    private MedicalRecordConsultRoom recordConsult;

    /**
     * 患者填写量表
     */
    private MedicalRecordScale recordScale;

    @ApiModelProperty(value = "病历设置")
    private List<MedicalRecordSettingBO> medicalRecordSettingList;

    /**
     * 病历失效状态 0：正常 1：删除
     */
    private Integer invalid;
    /**
     * 病历失效时间
     */
    @JsonFormat(pattern = DateUtil.DATE_TIME)
    private Date invalidTime;
    /**
     * <创建时间>
     */
    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    private Date createAt;
    /**
     * <创建人>
     */
    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    private String createBy;
    /**
     * <修改时间>
     */
    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    private Date changeAt;
    /**
     * <修改人>
     */
    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    private String changeBy;


    public enum ERelation {
        /**
         * 父亲 0
         */
        RELATION_FATHER(0, "父亲"),
        /**
         * 母亲 1
         */
        RELATION_MOTHER(1, "母亲"),
        /**
         * 兄弟姐妹 2
         */
        RELATION_BS(2, "兄弟姐妹"),
        /**
         * 子女 3
         */
        RELATION_SON(3, "子女"),
        /**
         * 丈夫 4
         */
        RELATION_HANS(4, "丈夫"),
        /**
         * 妻子 5
         */
        RELATION_WIFE(5, "妻子"),
        /**
         * 本人 6
         */
        RELATION_ONESELF(6, "本人"),
        /**
         * 其他家庭成员
         */
        RELATION_OTHER(7, "其他家庭成员");
        private Integer value;
        private String name;

        ERelation(Integer value, String name) {
            this.value = value;
            this.name = name;
        }

        public static ERelation val(Integer val) {
            if (val == null) {
                return null;
            }
            // values()方法返回enum实例的数组
            return Arrays.stream(values()).filter(s -> val.intValue() == s.getValue().intValue()).findFirst().orElse(null);
        }

        public Integer getValue() {
            return value;
        }

        public void setValue(Integer value) {
            this.value = value;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

    public enum AgeUnitEunm {
        /**
         * 周
         */
        WEEK("周"),
        /**
         * 个月
         */
        MONTH("个月"),
        /**
         * 岁
         */
        YEAR("岁");
        private String unit;

        AgeUnitEunm(String unit) {
            this.unit = unit;
        }

        public static AgeUnitEunm val(String unit) {
            if (StringUtils.isEmpty(unit)) {
                return null;
            }
            // values()方法返回enum实例的数组
            return Arrays.stream(values()).filter(s -> unit.equals(s.getUnit())).findFirst().orElse(null);
        }

        public String getUnit() {
            return unit;
        }
    }

    public enum GenderEnum {

        /**
         * 女
         */
        GENDER_FEMALE(0, "女"),
        /**
         * 男
         */
        GENDER_MALE(1, "男"),
        /**
         * 未知
         */
        GENDER_UNKNOWN(2, "未知");

        private Integer id;
        private String name;

        GenderEnum(Integer id, String name) {
            this.id = id;
            this.name = name;
        }

        public static GenderEnum val(Integer gender) {
            // values()方法返回enum实例的数组
            return Arrays.stream(values()).filter(s -> gender.intValue() == s.getId().intValue()).findFirst().orElse(null);
        }

        public Integer getId() {
            return id;
        }

        public String getName() {
            return name;
        }
    }


}
